#pragma once

#include "node.h"
#include "../../vmath/vec4.h"
#include "../cache/texture_cache.h"
#include "../cache/shader_cache.h"

namespace jlib {


struct ImageNode : public Node {

  using Node::Node;

  virtual void draw (const mat4 &pv, const mat4 &p, const mat4 &v, const mat4 &m) override;

  bool init (TexFrag *texfrag, Shader *shader = nullptr) noexcept;
  bool init (Texture *texture, Shader *shader = nullptr) noexcept;
  bool init (const std::string &path, FileDomain domain = FileDomain::Resource, Shader *shader = nullptr) noexcept;
  void clear () noexcept;

  void setShader (Shader *shader) noexcept;
  void setTexFrag (TexFrag *texFrag) noexcept;
  void setTexture (Texture *texture) noexcept;
  void setColor (const rgba &color) noexcept;
  void setBlendFunc (GLenum src, GLenum dst) noexcept;
  void setAnchor (const vec2 &anchor) noexcept;
  void setAnchor (float x, float y) noexcept;
  void setAnchorX (float x) noexcept;
  void setAnchorY (float y) noexcept;

  inline Texture *getTexture () noexcept { return this->_texFrag ? this->_texFrag->tex() : nullptr; }
  inline GLenum getSrcBlendFunc () const noexcept { return this->_srcFactor; }
  inline GLenum getDstBlendFunc () const noexcept { return this->_dstFactor; }

  inline vec2 getAnchor () const noexcept { return this->_anchor; }
  inline rgba getColor () const noexcept { return this->_color; }

  enum {
    u_tex = 0,
    u_pvm = 0,
    u_color = 1,
    a_position = 0,
    a_texCoord = 1,
  };
  static const char *VShader;
  static const char *FShader;
  static const std::string ShaderName;

protected:
  void resolveVerticesAndTexCoord () noexcept;

  Objptr<TexFrag> _texFrag;
  Objptr<Shader> _shader;

  rgba _color {1.0F, 1.0F, 1.0F, 1.0F};
  vec2 _vertices[4];
  vec2 _texCoord[4];
  vec2 _anchor {0.5F, 0.5F};

  GLenum _srcFactor {GL_SRC_ALPHA};
  GLenum _dstFactor {GL_ONE_MINUS_SRC_ALPHA};

  flags_type _imageNodeFlags {VerticesAndTexCoordDirty};

  constexpr static flags_type VerticesAndTexCoordDirty = 1;

}; // struct ImageNode


CLOSE_JLIB_NS
